home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 501-525 / disk_518 / post / post16s.lzh / postop2.c < prev    next >
Text File  |  1991-04-17  |  40KB  |  1,445 lines

  1. /* PostScript interpreter file "postop2.c" - operators (2) */
  2. /* (C) Adrian Aylward 1989, 1991 */
  3.  
  4. # include "post.h"
  5.  
  6. /* index */
  7.     
  8. void opindex(void)
  9. {   struct object *token1;
  10.     int num;
  11.     if (opernest < 1) error(errstackunderflow);
  12.     token1 = &operstack[opernest - 1];
  13.     if (token1->type != typeint) error(errtypecheck);
  14.     num = token1->value.ival;
  15.     if (num < 0 || num > opernest - 2) error(errrangecheck);
  16.     *token1 = *(token1 - num - 1);
  17. }
  18.  
  19. /* known */
  20.  
  21. void opknown(void)
  22. {   struct object token, *token1, *token2;
  23.     int bool;
  24.     if (opernest < 2) error(errstackunderflow);
  25.     token2 = &operstack[opernest - 1];
  26.     token1 = token2 - 1;
  27.     if (token1->type != typedict) error(errtypecheck);
  28.     bool = dictget(token1->value.vref, token2, &token, flagrprot);
  29.     token.type = typebool;
  30.     token.flags = 0;
  31.     token.length = 0;
  32.     token.value.ival = bool;
  33.     *token1 = token;
  34.     opernest -= 1;
  35. }
  36.  
  37. /* le */
  38.  
  39. void ople(void)
  40. {   struct object token, *token1, *token2;
  41.     if (opernest < 2) error(errstackunderflow);
  42.     token2 = &operstack[opernest - 1];
  43.     token1 = token2 - 1;
  44.     token.type = typebool;
  45.     token.flags = 0;
  46.     token.length = 0;
  47.     token.value.ival = (compare(token1, token2) <= 0);
  48.     *token1 = token;
  49.     opernest--;
  50. }
  51.  
  52. /* length */
  53.  
  54. void oplength(void)
  55. {   struct object token, *token1;
  56.     struct dictionary *dict;
  57.     struct name *name;
  58.     int length;
  59.     if (opernest < 1) error(errstackunderflow);
  60.     token1 = &operstack[opernest - 1];
  61.     if      (token1->type == typearray || token1->type == typepacked ||
  62.              token1->type == typestring)
  63.     {   if (token1->flags & flagrprot) error(errinvalidaccess);
  64.         length = token1->length;
  65.     }
  66.     else if (token1->type == typedict)
  67.     {   dict = vmdptr(token1->value.vref);
  68.         if (dict->flags & flagrprot) error(errinvalidaccess);
  69.         length = dict->full;
  70.     }
  71.     else if (token1->type == typename)
  72.     {   name = vmnptr(token1->value.vref);
  73.         length = name->length;
  74.     }
  75.     else
  76.         error(errtypecheck);
  77.     token.type = typeint;
  78.     token.flags = 0;
  79.     token.length = 0;
  80.     token.value.ival = length;
  81.     *token1 = token;
  82. }
  83.  
  84. /* ln */
  85.  
  86. void opln(void)
  87. {   struct object token, *token1;
  88.     if (opernest < 1) error(errstackunderflow);
  89.     token1 = &operstack[opernest - 1];
  90.     token = *token1;
  91.     if (token.type == typeint)
  92.     {   token.type = typereal;
  93.         token.value.rval = token.value.ival;
  94.     }
  95.     if (token.type == typereal)
  96.         token.value.rval = (float) log((double) token.value.rval);
  97.     else
  98.         error(errtypecheck);
  99.     *token1 = token;
  100. }
  101.  
  102. /* load */
  103.  
  104. void opload(void)
  105. {   struct object *token;
  106.     if (opernest < 1) error(errstackunderflow);
  107.     token = &operstack[opernest - 1];
  108.     if (dictfind(token, token) == -1) error(errundefined);
  109. }
  110.  
  111. /* log */
  112.  
  113. void oplog(void)
  114. {   struct object token, *token1;
  115.     if (opernest < 1) error(errstackunderflow);
  116.     token1 = &operstack[opernest - 1];
  117.     token = *token1;
  118.     if (token.type == typeint)
  119.     {   token.type = typereal;
  120.         token.value.rval = token.value.ival;
  121.     }
  122.     if (token.type == typereal)
  123.         token.value.rval = (float) log10((double) token.value.rval);
  124.     else
  125.         error(errtypecheck);
  126.     *token1 = token;
  127. }
  128.  
  129. /* loop */
  130.  
  131. void oploop(void)
  132. {   struct object token, *token1, *tokenx;
  133.     if (currtoken->flags & flagctrl)
  134.     {   token1 = &execstack[execnest - 2];
  135.         token1[2] = *token1;
  136.         execnest++;
  137.     }
  138.     else
  139.     {   if (opernest < 1) error(errstackunderflow);
  140.         token1 = &operstack[opernest - 1];
  141.         if (token1->type != typearray && token1->type != typepacked)
  142.             error(errtypecheck);
  143.         if (execnest + 3 > execstacksize) error(errexecstackoverflow);
  144.         tokenx = &execstack[execnest];
  145.         *tokenx++ = *token1;
  146.         token = *currtoken;
  147.         token.flags &= ~flagexec;
  148.         token.flags |= flagctrl | flagloop;
  149.         token.length = 2;
  150.         *tokenx = token;
  151.         execnest += 2;
  152.         opernest -= 1;
  153.     }
  154. }
  155.  
  156. /* lt */
  157.  
  158. void oplt(void)
  159. {   struct object token, *token1, *token2;
  160.     if (opernest < 2) error(errstackunderflow);
  161.     token2 = &operstack[opernest - 1];
  162.     token1 = token2 - 1;
  163.     token.type = typebool;
  164.     token.flags = 0;
  165.     token.length = 0;
  166.     token.value.ival = (compare(token1, token2) < 0);
  167.     *token1 = token;
  168.     opernest--;
  169. }
  170.  
  171. /* maxlength */
  172.  
  173. void opmaxlength(void)
  174. {   struct object token, *token1;
  175.     struct dictionary *dict;
  176.     if (opernest < 1) error(errstackunderflow);
  177.     token1 = &operstack[opernest - 1];
  178.     if (token1->type != typedict) error(errtypecheck);
  179.     dict = vmdptr(token1->value.vref);
  180.     if (dict->flags & flagrprot) error(errinvalidaccess);
  181.     token.type = typeint;
  182.     token.flags = 0;
  183.     token.length = 0;
  184.     token.value.ival = dict->size;
  185.     *token1 = token;
  186. }
  187.  
  188. /* mod */
  189.  
  190. void opmod(void)
  191. {   struct object *token1, *token2;
  192.     int num1, num2;
  193.     if (opernest < 2) error(errstackunderflow);
  194.     token2 = &operstack[opernest - 1];
  195.     token1 = token2 - 1;
  196.     if (token1->type != typeint || token2->type != typeint)
  197.         error(errtypecheck);
  198.     num1 = token1->value.ival;
  199.     num2 = token2->value.ival;
  200.     if (num2 == 0) error(errundefinedresult);
  201.     token1->value.ival = num1 % num2;
  202.     opernest--;
  203. }
  204.  
  205. /* mul */
  206.  
  207. void opmul(void)
  208. {   struct object token, *token1, *token2;
  209.     int num1, num2, tmp1, tmp2;
  210.     unsigned int neg;
  211.     if (opernest < 2) error(errstackunderflow);
  212.     token2 = &operstack[opernest - 1];
  213.     token1 = token2 - 1;
  214.     if (token1->type == typeint && token2->type == typeint)
  215.     {   num1 = token1->value.ival;
  216.         num2 = token2->value.ival;
  217.         neg = 0x7fffffff;
  218.         if (num1 < 0)
  219.         {   neg = ~neg;
  220.             num1 = -num1;
  221.         }
  222.         if (num2 < 0)
  223.         {   neg = ~neg;
  224.             num2 = -num2;
  225.         }
  226.         tmp1 = (unsigned) num1 >> 16;
  227.         tmp2 = (unsigned) num2 >> 16;
  228.         num1 &= 0xffff;
  229.         num2 &= 0xffff;
  230.         if (tmp1 == 0)
  231.         {   if (tmp2 == 0)
  232.             {   num1 *= num2;
  233.                 if ((unsigned) num1 <= neg)
  234.                 {   token1->value.ival = (neg == 0x7fffffff) ? num1 : -num1;
  235.                     opernest--;
  236.                     return;
  237.                 }
  238.             }
  239.             else
  240.             {   tmp2 *= num1;
  241.                 num1 *= num2;
  242.                 tmp1 = tmp2 + ((unsigned) num1 >> 16);
  243.                 num1 += tmp2 << 16;
  244.                 if ((tmp1 & 0xffff0000) == 0 && (unsigned) num1 <= neg)
  245.                 {   token1->value.ival = (neg == 0x7fffffff) ? num1 : -num1;
  246.                     opernest--;
  247.                     return;
  248.                 }
  249.             }
  250.         }
  251.         else
  252.             if (tmp2 == 0)
  253.             {   tmp1 *= num2;
  254.                 num2 *= num1;
  255.                 tmp2 = tmp1 + ((unsigned) num2 >> 16);
  256.                 num2 += tmp1 << 16;
  257.                 if ((tmp2 & 0xffff0000) == 0 && (unsigned) num2 <= neg)
  258.                 {   token1->value.ival = (neg == 0x7fffffff) ? num2 : -num2;
  259.                     opernest--;
  260.                     return;
  261.                 }
  262.             }
  263.          
  264.     }
  265.     token = *token1;
  266.     if (token.type == typeint)
  267.     {   token.type = typereal;
  268.         token.value.rval = token.value.ival;
  269.     }
  270.     else
  271.         if (token.type != typereal) error(errtypecheck);
  272.     if (token2->type == typeint)
  273.         token.value.rval *= token2->value.ival;
  274.     else
  275.     {   if (token2->type != typereal) error(errtypecheck);
  276.         token.value.rval *= token2->value.rval;
  277.     }
  278.     *token1 = token;
  279.     opernest--;
  280. }
  281.  
  282. /* ne */
  283.  
  284. void opne(void)
  285. {   struct object token, *token1, *token2;
  286.     if (opernest < 2) error(errstackunderflow);
  287.     token2 = &operstack[opernest - 1];
  288.     token1 = token2 - 1;
  289.     token.type = typebool;
  290.     token.flags = 0;
  291.     token.length = 0;
  292.     token.value.ival = !equal(token1, token2);
  293.     *token1 = token;
  294.     opernest--;
  295. }
  296.  
  297. /* neg */
  298.  
  299. void opneg(void)
  300. {   struct object *token1;
  301.     int num1;
  302.     if (opernest < 1) error(errstackunderflow);
  303.     token1 = &operstack[opernest - 1];
  304.     if      (token1->type == typeint)
  305.     {   num1 = token1->value.ival;
  306.         if (num1 < 0)
  307.         {   num1 = -num1;
  308.             if (num1 < 0)
  309.             {   token1->type = typereal;
  310.                 token1->value.rval = -((float) num1);
  311.             }
  312.             else
  313.                 token1->value.ival = num1;
  314.         }
  315.         else
  316.             token1->value.ival = -num1;
  317.     }
  318.     else if (token1->type == typereal)
  319.         token1->value.rval = -token1->value.rval;
  320.     else
  321.         error(errtypecheck);
  322. }
  323.  
  324. /* noaccess */
  325.  
  326. void opnoaccess(void)
  327. {   struct object *token1;
  328.     int type;
  329.     if (opernest < 1) error(errstackunderflow);
  330.     token1 = &operstack[opernest - 1];
  331.     type = token1->type;
  332.     if      (type == typefile || type == typestring ||
  333.              type == typearray || type == typepacked)
  334.         token1->flags |= (flagwprot | flagrprot | flagxprot);
  335.     else if (type == typedict)
  336.         vmdptr(token1->value.vref)->flags |= (flagwprot | flagrprot);
  337.     else
  338.         error(errtypecheck);
  339. }
  340.  
  341. /* not */
  342.  
  343. void opnot(void)
  344. {   struct object *token1;
  345.     if (opernest < 1) error(errstackunderflow);
  346.     token1 = &operstack[opernest - 1];
  347.     if      (token1->type == typebool)
  348.         token1->value.ival = !token1->value.ival;
  349.     else if (token1->type == typeint)
  350.         token1->value.ival = ~token1->value.ival;
  351.     else
  352.         error(errtypecheck);
  353. }
  354.  
  355. /* null */
  356.  
  357. void opnull(void)
  358. {   struct object token;
  359.     if (opernest == operstacksize) error(errstackoverflow);
  360.     token.type = typenull;
  361.     token.flags = 0;
  362.     token.length = 0;
  363.     token.value.ival = 0;
  364.     operstack[opernest++] = token;
  365. }
  366.  
  367. /* or */
  368.  
  369. void opor(void)
  370. {   struct object *token1, *token2;
  371.     if (opernest < 2) error(errstackunderflow);
  372.     token2 = &operstack[opernest - 1];
  373.     token1 = token2 - 1;
  374.     if ((token1->type == typebool && token2->type == typebool) ||
  375.         (token1->type == typeint  && token2->type == typeint))
  376.         token1->value.ival |= token2->value.ival;
  377.     else
  378.         error(errtypecheck);
  379.     opernest--;
  380. }
  381.  
  382. /* packedarray */
  383.  
  384. void oppackedarray(void)
  385. {   struct object token, *token1, *aptr;
  386.     int length;
  387.     if (opernest < 1) error(errstackunderflow);
  388.     token1 = &operstack[opernest - 1];
  389.     if (token1->type != typeint) error(errtypecheck);
  390.     length = token1->value.ival;
  391.     if (length < 0) error(errrangecheck);
  392.     if (opernest < length + 1) error(errstackunderflow);
  393.     aptr = token1 - length;
  394.     token.type = typepacked;
  395.     token.flags = flagwprot;
  396.     token.length = length;
  397.     token.value.vref = arraypack(aptr, length);
  398.     *aptr = token;
  399.     opernest -= length;
  400. }
  401.  
  402. /* pop */
  403.  
  404. void oppop(void)
  405. {   if (opernest < 1) error(errstackunderflow);
  406.     opernest -= 1;
  407. }
  408.  
  409. /* print */
  410.  
  411. void opprint(void)
  412. {   struct object *token1;
  413.     if (opernest < 1) error(errstackunderflow);
  414.     token1 = &operstack[opernest - 1];
  415.     if (token1->type != typestring) error(errtypecheck);
  416.     if (token1->flags & flagrprot) error(errinvalidaccess);
  417.     if (sstdout)
  418.         putmem(sstdout, vmsptr(token1->value.vref), token1->length);
  419.     opernest--;
  420. }
  421.  
  422. /* prompts */
  423.  
  424. void opprompts(void)
  425. {   struct object *token1, *token2;
  426.     if (opernest < 2) error(errstackunderflow);
  427.     token2 = &operstack[opernest - 1];
  428.     token1 = token2 - 1;
  429.     if (token1->type != typestring) error(errtypecheck);
  430.     if (token1->flags & flagrprot) error(errinvalidaccess);
  431.     if (token1->length > promptsize) error(errrangecheck);
  432.     if (token2->type != typestring) error(errtypecheck);
  433.     if (token2->flags & flagrprot) error(errinvalidaccess);
  434.     if (token2->length > promptsize) error(errrangecheck);
  435.     memcpy(prompt1, vmsptr(token1->value.vref), token1->length);
  436.     prompt1[token1->length] = 0;
  437.     memcpy(prompt2, vmsptr(token2->value.vref), token2->length);
  438.     prompt2[token2->length] = 0;
  439.     opernest -= 2;
  440. }
  441.  
  442. /* pstack */
  443.  
  444. void oppstack(void)
  445. {   int nest = opernest;
  446.     if (sstdout)
  447.         while (nest)
  448.         {   printeqeq(sstdout, &operstack[--nest], 0, 0);
  449.             putch(sstdout, '\n');
  450.         }
  451. }
  452.  
  453. /* put */
  454.  
  455. void opput(void)
  456. {   struct object *token1, *token2, *token3;
  457.     int num;
  458.     if (opernest < 3) error(errstackunderflow);
  459.     token3 = &operstack[opernest - 1];
  460.     token2 = token3 - 1;
  461.     token1 = token2 - 1;
  462.     if (token1->type == typedict)
  463.         dictput(token1->value.vref, token2, token3);
  464.     else
  465.     {   if (token2->type != typeint) error(errtypecheck);
  466.         num = token2->value.ival;
  467.         if      (token1->type == typestring)
  468.         {   if (token3->type != typeint) error(errtypecheck);
  469.             if (token1->flags & flagwprot) error(errinvalidaccess);
  470.             if (num < 0 || num >= token1->length) error(errrangecheck);
  471.             vmsptr(token1->value.vref)[num] = token3->value.ival;
  472.         }
  473.         else if (token1->type == typearray)
  474.         {   if (token1->flags & flagwprot) error(errinvalidaccess);
  475.             if (num < 0 || num >= token1->length) error(errrangecheck);
  476.             arraysave(token1->value.vref, token1->length);
  477.             vmaptr(token1->value.vref)[num] = *token3;
  478.         }
  479.         else
  480.             error(errtypecheck);
  481.     }
  482.     opernest -= 3;
  483. }
  484.  
  485. /* putinterval */
  486.  
  487. void opputinterval(void)
  488. {   struct object *token1, *token2, *token3;
  489.     int num, len;
  490.     if (opernest < 3) error(errstackunderflow);
  491.     token3 = &operstack[opernest - 1];
  492.     token2 = token3 - 1;
  493.     token1 = token2 - 1;
  494.     if (token2->type != typeint) error(errtypecheck);
  495.     num = token2->value.ival;
  496.     if (token3->type != token1->type) error(errtypecheck);
  497.     len = token3->length;
  498.     if      (token1->type == typestring)
  499.     {   if (token1->flags & flagwprot) error(errinvalidaccess);
  500.         if (token3->flags & flagrprot) error(errinvalidaccess);
  501.         if (num < 0 || num > token1->length) error(errrangecheck);
  502.         if (len < 0 || num + len > token1->length) error(errrangecheck);
  503.         memcpy(vmsptr(token1->value.vref) + num,
  504.                vmsptr(token3->value.vref), len);
  505.     }
  506.     else if (token1->type == typearray)
  507.     {   if (token1->flags & flagwprot) error(errinvalidaccess);
  508.         if (token3->flags & flagrprot) error(errinvalidaccess);
  509.         if (num < 0 || num > token1->length) error(errrangecheck);
  510.         if (len < 0 || num + len > token1->length) error(errrangecheck);
  511.         arraysave(token1->value.vref, token1->length);
  512.         arraycopy(vmaptr(token1->value.vref) + num,
  513.                   vmaptr(token3->value.vref), len);
  514.     }
  515.     else
  516.         error(errtypecheck);
  517.     opernest -= 3;
  518. }
  519.  
  520. /* quit */
  521.  
  522. void opquit(void)
  523. {   execnest = 0;
  524.     errorjmp(0, 1);
  525. }
  526.  
  527. /* rand */
  528.  
  529. void oprand(void)
  530. {   struct object token;
  531.     if (opernest == operstacksize) error(errstackoverflow);
  532.     random *= 0x41c64e6d;
  533.     random += 0x3039;
  534.     token.type = typeint;
  535.     token.flags = 0;
  536.     token.length = 0;
  537.     token.value.ival = random >> 1;
  538.     operstack[opernest++] = token;
  539. }
  540.  
  541. /* rcheck */
  542.  
  543. void oprcheck(void)
  544. {   struct object token, *token1;
  545.     int type, bool;
  546.     if (opernest < 1) error(errstackunderflow);
  547.     token1 = &operstack[opernest - 1];
  548.     type = token1->type;
  549.     if      (type == typefile || type == typestring ||
  550.              type == typearray || type == typepacked)
  551.         bool = ((token1->flags & flagrprot) == 0);
  552.     else if (type == typedict)
  553.         bool = ((vmdptr(token1->value.vref)->flags & flagrprot) == 0);
  554.     else
  555.         error(errtypecheck);
  556.     token.type = typebool;
  557.     token.flags = 0;
  558.     token.length = 0;
  559.     token.value.ival = bool;
  560.     *token1 = token;
  561. }
  562.  
  563. /* read */
  564.  
  565. void opread(void)
  566. {   struct object token, *token1;
  567.     int ch;
  568.     if (opernest < 1) error(errstackunderflow);
  569.     if (opernest == operstacksize) error(errstackoverflow);
  570.     token1 = &operstack[opernest - 1];
  571.     if (token1->type != typefile) error(errtypecheck);
  572.     if (token1->flags & flagrprot) error(errinvalidaccess);
  573.     if (filecheck(token1, openread) == NULL) error(errioerror);
  574.     ch = readch(token1, -2);
  575.     token.flags = 0;
  576.     token.length = 0;
  577.     if (ch == EOF)
  578.     {   fileclose(token1);
  579.         token.value.ival = 0;
  580.     }
  581.     else
  582.     {   token.type = typeint;
  583.         token.value.ival = ch;
  584.         *token1++ = token;
  585.         token.value.ival = 1;
  586.         opernest++;
  587.     }
  588.     token.type = typebool;
  589.     *token1 = token;
  590. }
  591.  
  592. /* readhexstring */
  593.  
  594. void opreadhexstring(void)
  595. {   struct object token, *token1, *token2;
  596.     char *sptr;
  597.     int ch, length, num, dig, sw;
  598.     if (opernest < 2) error(errstackunderflow);
  599.     token2 = &operstack[opernest - 1];
  600.     token1 = token2 - 1;
  601.     if (token1->type != typefile) error(errtypecheck);
  602.     if (token1->flags & flagrprot) error(errinvalidaccess);
  603.     if (filecheck(token1, openread) == NULL) error(errioerror);
  604.     if (token2->type != typestring) error(errtypecheck);
  605.     if (token2->flags & flagwprot) error(errinvalidaccess);
  606.     length = 0;
  607.     sptr = vmsptr(token2->value.vref);
  608.     ch = 0;
  609.     sw = 1;
  610.     while (length < token2->length)
  611.     {   ch = readch(token1, -1);
  612.         if (ch == EOF) break;
  613.         dig = digitval(ch);
  614.         if (dig >= 16) continue;
  615.         if (sw)
  616.         {   sw = 0;
  617.             num = dig * 16;
  618.         }
  619.         else
  620.         {   sw = 1;
  621.             num += dig;
  622.             *sptr++ = num;
  623.             length++;
  624.         }
  625.     }
  626.     token = *token2;
  627.     token.length = length;
  628.     *token1 = token;
  629.     token.type = typebool;
  630.     token.flags = 0;
  631.     token.length = 0;
  632.     token.value.ival = (ch != EOF);
  633.     *token2 = token;
  634. }
  635.  
  636. /* readline */
  637.  
  638. void opreadline(void)
  639. {   struct object token, *token1, *token2;
  640.     char *sptr;
  641.     int ch, length;
  642.     if (opernest < 2) error(errstackunderflow);
  643.     token2 = &operstack[opernest - 1];
  644.     token1 = token2 - 1;
  645.     if (token1->type != typefile) error(errtypecheck);
  646.     if (token1->flags & flagrprot) error(errinvalidaccess);
  647.     if (filecheck(token1, openread) == NULL) error(errioerror);
  648.     if (token2->type != typestring) error(errtypecheck);
  649.     if (token2->flags & flagwprot) error(errinvalidaccess);
  650.     length = 0;
  651.     sptr = vmsptr(token2->value.vref);
  652.     ch = 0;
  653.     for (;;)
  654.     {   ch = readch(token1, -1);
  655.         if (ch == '\n' || ch == EOF) break;
  656.         if (length == token2->length) error(errrangecheck);
  657.         *sptr++ = ch;
  658.         length++;
  659.     }
  660.     token = *token2;
  661.     token.length = length;
  662.     *token1 = token;
  663.     token.type = typebool;
  664.     token.flags = 0;
  665.     token.length = 0;
  666.     token.value.ival = (ch != EOF);
  667.     *token2 = token;
  668. }
  669.  
  670. /* readonly */
  671.  
  672. void opreadonly(void)
  673. {   struct object *token1;
  674.     struct dictionary *dict;
  675.     int type;
  676.     if (opernest < 1) error(errstackunderflow);
  677.     token1 = &operstack[opernest - 1];
  678.     type = token1->type;
  679.     if      (type == typefile || type == typestring ||
  680.              type == typearray || type == typepacked)
  681.     {   if (token1->flags & flagrprot) error(errinvalidaccess);
  682.         token1->flags |= flagwprot;
  683.     }
  684.     else if (type == typedict)
  685.     {   dict = vmdptr(token1->value.vref);
  686.         if (dict->flags & flagrprot) error(errinvalidaccess);
  687.         dict->flags |= flagwprot;
  688.     }
  689.     else
  690.         error(errtypecheck);
  691. }
  692.  
  693. /* readstring */
  694.  
  695. void opreadstring(void)
  696. {   struct object token, *token1, *token2;
  697.     char *sptr;
  698.     int ch, length;
  699.     if (opernest < 2) error(errstackunderflow);
  700.     token2 = &operstack[opernest - 1];
  701.     token1 = token2 - 1;
  702.     if (token1->type != typefile) error(errtypecheck);
  703.     if (token1->flags & flagrprot) error(errinvalidaccess);
  704.     if (filecheck(token1, openread) == NULL) error(errioerror);
  705.     if (token2->type != typestring) error(errtypecheck);
  706.     if (token2->flags & flagwprot) error(errinvalidaccess);
  707.     length = 0;
  708.     sptr = vmsptr(token2->value.vref);
  709.     ch = 0;
  710.     while (length < token2->length)
  711.     {   ch = readch(token1, -2);
  712.         if (ch == EOF) break;
  713.         *sptr++ = ch;
  714.         length++;
  715.     }
  716.     token = *token2;
  717.     token.length = length;
  718.     *token1 = token;
  719.     token.type = typebool;
  720.     token.flags = 0;
  721.     token.length = 0;
  722.     token.value.ival = (ch != EOF);
  723.     *token2 = token;
  724. }
  725.  
  726. /* repeat */
  727.  
  728. void oprepeat(void)
  729. {   struct object token, *token1, *token2, *tokenx;
  730.     if (currtoken->flags & flagctrl)
  731.     {   token2 = &execstack[execnest - 2];
  732.         token1 = token2 - 1;
  733.         if (token1->value.ival <= 0)
  734.         {   execnest -= 3;
  735.             return;
  736.         }
  737.         token1->value.ival--;
  738.         token2[2] = *token2;
  739.         execnest++;
  740.     }
  741.     else
  742.     {   if (opernest < 2) error(errstackunderflow);
  743.         token2 = &operstack[opernest - 1];
  744.         token1 = token2 - 1;
  745.         if (token1->type != typeint) error(errtypecheck);
  746.         if (token2->type != typearray && token2->type != typepacked)
  747.             error(errtypecheck);
  748.         if (execnest + 4 > execstacksize) error(errexecstackoverflow);
  749.         tokenx = &execstack[execnest];
  750.         *tokenx++ = *token1;
  751.         *tokenx++ = *token2;
  752.         token = *currtoken;
  753.         token.flags &= ~flagexec;
  754.         token.flags |= flagctrl | flagloop;
  755.         token.length = 3;
  756.         *tokenx = token;
  757.         execnest += 3;
  758.         opernest -= 2;
  759.     }
  760. }
  761.  
  762. /* resetfile */
  763.  
  764. void opresetfile(void)
  765. {   struct object *token1;
  766.     if (opernest < 1) error(errstackunderflow);
  767.     token1 = &operstack[opernest - 1];
  768.     if (token1->type != typefile) error(errtypecheck);
  769.     if (filecheck(token1, openread | openwrite) == NULL) error(errioerror);
  770.     opernest--;
  771. }
  772.  
  773. /* restore */
  774.  
  775. void oprestore(void)
  776. {   struct object *token1;
  777.     if (opernest < 1) error(errstackunderflow);
  778.     token1 = &operstack[opernest - 1];
  779.     if (token1->type != typesave) error(errtypecheck);
  780.     vmrest(token1->length, token1->value.ival);
  781.     opernest--;
  782. }
  783.  
  784. /* roll */
  785.     
  786. void oproll(void)
  787. {   struct object *token1, *token2;
  788.     int num, dir, shf;
  789.     if (opernest < 2) error(errstackunderflow);
  790.     token2 = &operstack[opernest - 1];
  791.     token1 = token2 - 1;
  792.     if (token1->type != typeint) error(errtypecheck);
  793.     num = token1->value.ival;
  794.     if (token2->type != typeint) error(errtypecheck);
  795.     dir = token2->value.ival;
  796.     if (num < 0 || num > opernest - 2) error(errrangecheck);
  797.     dir = dir % num;
  798.     shf = num - dir;
  799.     if (opernest + shf - 2 > operstacksize) error(errstackoverflow);
  800.     opernest -= 2;
  801.     arraycopy(token1, token1 - num, shf);
  802.     arraycopy(token1 - num, token1 - dir, num);
  803. }
  804.  
  805. /* round */
  806.  
  807. void opround(void)
  808. {   struct object *token1;
  809.     if (opernest < 1) error(errstackunderflow);
  810.     token1 = &operstack[opernest - 1];
  811.     if (token1->type == typeint)
  812.         return;
  813.     else if (token1->type == typereal)
  814.         token1->value.rval = (float) floor((double) token1->value.rval + .5);
  815.     else
  816.         error(errtypecheck);
  817. }
  818.  
  819. /* rrand */
  820.  
  821. void oprrand(void)
  822. {   struct object token;
  823.     if (opernest == operstacksize) error(errstackoverflow);
  824.     token.type = typeint;
  825.     token.flags = 0;
  826.     token.length = 0;
  827.     token.value.ival = random;
  828.     operstack[opernest++] = token;
  829. }
  830.  
  831. /* run */
  832.  
  833. void oprun(void)
  834. {   struct object token, *token1, *tokenx;
  835.     if (currtoken->flags & flagctrl)
  836.         execnest -= 2;
  837.     else
  838.     {   if (opernest < 1) error(errstackunderflow);
  839.         token1 = &operstack[opernest - 1];
  840.         if (token1->type != typestring) error(errtypecheck);
  841.         if (token1->flags & flagrprot) error(errinvalidaccess);
  842.         if (execnest + 3 > execstacksize) error(errexecstackoverflow);
  843.         tokenx = &execstack[execnest];
  844.         fileopen(&token, openread, vmsptr(token1->value.vref),
  845.                          token1->length);
  846.         token.flags |= flagexec;
  847.         tokenx[0] = token;
  848.         tokenx[2] = token;
  849.         token = *currtoken;
  850.         token.flags &= ~flagexec;
  851.         token.flags |= flagctrl | flagrun;
  852.         token.length = 2;
  853.         tokenx[1] = token;
  854.         execnest += 3;
  855.         opernest--;
  856.     }
  857. }
  858.  
  859. /* save */
  860.  
  861. void opsave(void)
  862. {   struct object token;
  863.     if (opernest == operstacksize) error(errstackoverflow);
  864.     vmsave(&token);
  865.     operstack[opernest++] = token;
  866. }
  867.  
  868. /* search */
  869.  
  870. void opsearch(void)
  871. {   struct object *token1, *token2;
  872.     char *sptr1, *sptr2;
  873.     int len1, len2, offs, bool;
  874.     struct object token;
  875.     if (opernest < 2) error(errstackunderflow);
  876.     if (opernest + 2 > operstacksize) error(errstackoverflow);
  877.     token2 = &operstack[opernest - 1];
  878.     token1 = token2 - 1;
  879.     if (token1->type != typestring) error(errtypecheck);
  880.     if (token1->flags & flagrprot) error(errinvalidaccess);
  881.     len1 = token1->length;
  882.     sptr1 = vmsptr(token1->value.vref);
  883.     if (token2->type != typestring) error(errtypecheck);
  884.     if (token2->flags & flagrprot) error(errinvalidaccess);
  885.     len2 = token2->length;
  886.     sptr2 = vmsptr(token2->value.vref);
  887.     offs = 0;
  888.     bool = 0;
  889.     while (offs + len2 <= len1)
  890.     {   if (memcmp(sptr1 + offs, sptr2, len2) == 0)
  891.         {   bool = 1;
  892.             break;
  893.         }
  894.         offs++;
  895.     }
  896.     if (bool)
  897.     {   token = *token1;
  898.         token.length = offs;
  899.         *(token2 + 1) = token;
  900.         token.length = len2;
  901.         token.value.vref = token1->value.vref + offs;
  902.         *token2 = token;
  903.         token.length = len1 - offs - len2;
  904.         token.value.vref = token1->value.vref + offs + len2;
  905.         *token1 = token;
  906.         token2 += 2;
  907.         opernest += 2;
  908.     }
  909.     token.type = typebool;
  910.     token.flags = 0;
  911.     token.length = 0;
  912.     token.value.ival = bool;
  913.     *token2 = token;
  914. }
  915.  
  916. /* setpacking */
  917.  
  918. void opsetpacking(void)
  919. {   struct object *token1;
  920.     if (opernest < 1) error(errstackunderflow);
  921.     token1 = &operstack[opernest - 1];
  922.     if (token1->type != typebool) error(errtypecheck);
  923.     packing = token1->value.ival;
  924.     opernest--;
  925. }
  926.  
  927. /* sin */
  928.  
  929. void opsin(void)
  930. {   struct object token, *token1;
  931.     if (opernest < 1) error(errstackunderflow);
  932.     token1 = &operstack[opernest - 1];
  933.     token = *token1;
  934.     if (token.type == typeint)
  935.     {   token.type = typereal;
  936.         token.value.rval = token.value.ival;
  937.     }
  938.     if (token.type == typereal)
  939.         token.value.rval = (float) sin((double) token.value.rval * degtorad);
  940.     else
  941.         error(errtypecheck);
  942.     *token1 = token;
  943. }
  944.  
  945. /* sqrt */
  946.  
  947. void opsqrt(void)
  948. {   struct object token, *token1;
  949.     if (opernest < 1) error(errstackunderflow);
  950.     token1 = &operstack[opernest - 1];
  951.     token = *token1;
  952.     if (token.type == typeint)
  953.     {   token.type = typereal;
  954.         token.value.rval = token.value.ival;
  955.     }
  956.     if (token.type == typereal)
  957.     {   if (token.value.rval < 0.0) error(errrangecheck);
  958.         token.value.rval = (float) sqrt((double) token.value.rval);
  959.     }
  960.     else
  961.         error(errtypecheck);
  962.     *token1 = token;
  963. }
  964.  
  965. /* srand */
  966.  
  967. void opsrand(void)
  968. {   struct object *token1;
  969.     if (opernest < 1) error(errstackunderflow);
  970.     token1 = &operstack[opernest - 1];
  971.     if (token1->type != typeint) error(errrangecheck);
  972.     random = token1->value.ival;
  973.     opernest--;
  974. }
  975.  
  976. /* stack */
  977.  
  978. void opstack(void)
  979. {   int nest = opernest;
  980.     if (sstdout)
  981.         while (nest)
  982.         {   printequals(sstdout, &operstack[--nest]);
  983.             putch(sstdout, '\n');
  984.         }
  985. }
  986.  
  987. /* status */
  988.  
  989. void opstatus(void)
  990. {   struct object token, *token1;
  991.     if (opernest < 1) error(errstackunderflow);
  992.     token1 = &operstack[opernest - 1];
  993.     if (token1->type != typefile) error(errtypecheck);
  994.     token.type = typebool;
  995.     token.flags = 0;
  996.     token.length = 0;
  997.     token.value.ival =
  998.         (filecheck(token1, openread | openwrite) != NULL);
  999.     *token1 = token;
  1000. }
  1001.  
  1002. /* stop */
  1003.  
  1004. void opstop(void)
  1005. {   stop();
  1006.     error(errinvalidstop);
  1007. }
  1008.  
  1009. /* stopped */
  1010.  
  1011. void opstopped(void)
  1012. {   struct object token, *token1, *tokenx;
  1013.     if (opernest == operstacksize) error(errstackoverflow);
  1014.     if (currtoken->flags & flagctrl)
  1015.     {   if (opernest == operstacksize) error(errstackoverflow);
  1016.         token.type = typebool;
  1017.         token.flags = 0;
  1018.         token.length = 0;
  1019.         token.value.ival = 0;
  1020.         operstack[opernest++] = token;
  1021.         execnest -= 2;
  1022.     }
  1023.     else
  1024.     {   if (opernest < 1) error(errstackunderflow);
  1025.         token1 = &operstack[opernest - 1];
  1026.         if (execnest + 3 > execstacksize) error(errexecstackoverflow);
  1027.         tokenx = &execstack[execnest];
  1028.         tokenx[0] = *token1;
  1029.         token = *currtoken;
  1030.         token.flags &= ~flagexec;
  1031.         token.flags |= flagctrl | flagstop;
  1032.         token.length = inest;
  1033.         tokenx[1] = token;
  1034.         tokenx[2] = *token1;
  1035.         execnest += 3;
  1036.         opernest--;
  1037.     }
  1038. }
  1039.  
  1040. /* store */
  1041.  
  1042. void opstore(void)
  1043. {   struct object token, *token1, *token2;
  1044.     int nest;
  1045.     if (opernest < 2) error(errstackunderflow);
  1046.     token2 = &operstack[opernest - 1];
  1047.     token1 = token2 - 1;
  1048.     nest = dictfind(token1, &token);
  1049.     if (nest == -1) nest = dictnest - 1;
  1050.     dictput(dictstack[nest].value.vref, token1, token2);
  1051.     opernest -= 2;
  1052. }
  1053.  
  1054. /* string */
  1055.  
  1056. void opstring(void)
  1057. {   struct object token, *token1;
  1058.     int length;
  1059.     if (opernest < 1) error(errstackunderflow);
  1060.     token1 = &operstack[opernest - 1];
  1061.     if (token1->type != typeint) error(errtypecheck);
  1062.     length = token1->value.ival;
  1063.     if (length < 0 || length > 65535) error(errrangecheck);
  1064.     token.type = typestring;
  1065.     token.flags = 0;
  1066.     token.length = token1->value.ival;
  1067.     token.value.vref = vmalloc(length);
  1068.     *token1 = token;
  1069. }
  1070.  
  1071. /* sub */
  1072.  
  1073. void opsub(void)
  1074. {   struct object token, *token1, *token2;
  1075.     int num1, num2;
  1076.     if (opernest < 2) error(errstackunderflow);
  1077.     token2 = &operstack[opernest - 1];
  1078.     token1 = token2 - 1;
  1079.     if (token1->type == typeint && token2->type == typeint)
  1080.     {   num1 = token1->value.ival;
  1081.         num2 = token2->value.ival;
  1082.         if      (num1 > 0 && num2 < 0)
  1083.         {   num1 -= num2;
  1084.             if (num1 > 0)
  1085.             {   token1->value.ival = num1;
  1086.                 opernest--;
  1087.                 return;
  1088.             }
  1089.         }
  1090.         else if (num1 < 0 && num2 > 0)
  1091.         {   num1 -= num2;
  1092.             if (num1 < 0)
  1093.             {   token1->value.ival = num1;
  1094.                 opernest--;
  1095.                 return;
  1096.             }
  1097.         }
  1098.         else
  1099.         {   num1 -= num2;
  1100.             token1->value.ival = num1;
  1101.             opernest--;
  1102.             return;
  1103.         }
  1104.     }
  1105.     token = *token1;
  1106.     if (token.type == typeint)
  1107.     {   token.type = typereal;
  1108.         token.value.rval = token.value.ival;
  1109.     }
  1110.     else
  1111.         if (token.type != typereal) error(errtypecheck);
  1112.     if (token2->type == typeint)
  1113.         token.value.rval -= token2->value.ival;
  1114.     else
  1115.     {   if (token2->type != typereal) error(errtypecheck);
  1116.         token.value.rval -= token2->value.rval;
  1117.     }
  1118.     *token1 = token;
  1119.     opernest--;
  1120. }
  1121.  
  1122. /* token */
  1123.  
  1124. void optoken(void)
  1125. {   struct object token, *token1;
  1126.     int bool;
  1127.     if (opernest < 1) error(errstackunderflow);
  1128.     token1 = &operstack[opernest - 1];
  1129.     if     (token1->type == typefile)
  1130.     {    if (opernest + 1 > operstacksize) error(errstackoverflow);
  1131.          bool = scantoken(&token, token1, -1);
  1132.          if (bool)
  1133.          {   *token1++ = token;
  1134.              opernest++;
  1135.          }
  1136.          else
  1137.              fileclose(token1);
  1138.     }
  1139.     else if (token1->type == typestring)
  1140.     {    if (opernest + 2 > operstacksize) error(errstackoverflow);
  1141.          bool = scantoken(&token, token1, -1);
  1142.          if (bool)
  1143.          {   token1++;
  1144.              *token1++ = token;
  1145.              opernest += 2;
  1146.          }
  1147.     }
  1148.     else
  1149.         error(errtypecheck);
  1150.     token.type = typebool;
  1151.     token.flags = 0;
  1152.     token.length = 0;
  1153.     token.value.ival = bool;
  1154.     *token1 = token;
  1155. }
  1156.  
  1157. /* truncate */
  1158.  
  1159. void optruncate(void)
  1160. {   struct object *token1;
  1161.     if (opernest < 1) error(errstackunderflow);
  1162.     token1 = &operstack[opernest - 1];
  1163.     if (token1->type == typeint)
  1164.         return;
  1165.     else if (token1->type == typereal)
  1166.         if (token1->value.rval > 0.0)
  1167.             token1->value.rval = (float) floor((double) token1->value.rval);
  1168.         else
  1169.             token1->value.rval = (float) ceil((double) token1->value.rval);
  1170.     else
  1171.         error(errtypecheck);
  1172. }
  1173.  
  1174. /* type */
  1175.  
  1176. void optype(void)
  1177. {   struct object token, *token1;
  1178.     char *sptr;
  1179.     if (opernest < 1) error(errstackunderflow);
  1180.     token1 = &operstack[opernest - 1];
  1181.     sptr = typetable[token1->type];
  1182.     nametoken(&token, sptr, -1, flagexec);
  1183.     *token1 = token;
  1184. }
  1185.  
  1186. /* usertime */
  1187.  
  1188. void opusertime(void)
  1189. {   struct object token;
  1190.     if (opernest == operstacksize) error(errstackoverflow);
  1191.     token.type = typeint;
  1192.     token.flags = 0;
  1193.     token.length = 0;
  1194.     token.value.ival = usertime();
  1195.     operstack[opernest++] = token;
  1196. }
  1197.  
  1198. /* vmhwm */
  1199.  
  1200. void opvmhwm(void)
  1201. {   struct object token, *token1;
  1202.     if (opernest + 2 > operstacksize) error(errstackoverflow);
  1203.     token1 = &operstack[opernest];
  1204.     token.type = typeint;
  1205.     token.flags = 0;
  1206.     token.length = 0;
  1207.     token.value.ival = vmhwm;
  1208.     token1[0] = token;
  1209.     token.value.ival = vmmax;
  1210.     token1[1] = token;
  1211.     opernest += 2;
  1212.     vmhwm = vmused;
  1213. }
  1214.  
  1215. /* vmstatus */
  1216.  
  1217. void opvmstatus(void)
  1218. {   struct object token, *token1;
  1219.     if (opernest + 3 > operstacksize) error(errstackoverflow);
  1220.     token1 = &operstack[opernest];
  1221.     token.type = typeint;
  1222.     token.flags = 0;
  1223.     token.length = 0;
  1224.     token.value.ival = vmnest;
  1225.     token1[0] = token;
  1226.     token.value.ival = vmused;
  1227.     token1[1] = token;
  1228.     token.value.ival = vmmax;
  1229.     token1[2] = token;
  1230.     opernest += 3;
  1231. }
  1232.  
  1233. /* wcheck */
  1234.  
  1235. void opwcheck(void)
  1236. {   struct object token, *token1;
  1237.     int type, bool;
  1238.     if (opernest < 1) error(errstackunderflow);
  1239.     token1 = &operstack[opernest - 1];
  1240.     type = token1->type;
  1241.     if      (type == typefile || type == typestring ||
  1242.              type == typearray || type == typepacked)
  1243.         bool = ((token1->flags & flagwprot) == 0);
  1244.     else if (type == typedict)
  1245.         bool = ((vmdptr(token1->value.vref)->flags & flagwprot) == 0);
  1246.     else
  1247.         error(errtypecheck);
  1248.     token.type = typebool;
  1249.     token.flags = 0;
  1250.     token.length = 0;
  1251.     token.value.ival = bool;
  1252.     *token1 = token;
  1253. }
  1254.  
  1255. /* where */
  1256.  
  1257. void opwhere(void)
  1258. {   struct object token, *token1;
  1259.     int nest;
  1260.     if (opernest < 1) error(errstackunderflow);
  1261.     if (opernest + 2 > operstacksize) error(errstackoverflow);
  1262.     token1 = &operstack[opernest - 1];
  1263.     nest = dictfind(token1, &token);
  1264.     token.type = typebool;
  1265.     token.flags = 0;
  1266.     token.length = 0;
  1267.     token.value.ival = 0;
  1268.     if (nest != -1)
  1269.     {   *token1++ = dictstack[nest];
  1270.         opernest++;
  1271.         token.value.ival = 1;
  1272.     }
  1273.     *token1 = token;
  1274. }
  1275.  
  1276. /* write */
  1277.  
  1278. void opwrite(void)
  1279. {   struct object *token1, *token2;
  1280.     struct file *file;
  1281.     if (opernest < 2) error(errstackunderflow);
  1282.     token2 = &operstack[opernest - 1];
  1283.     token1 = token2 - 1;
  1284.     if (token1->type != typefile) error(errtypecheck);
  1285.     if (token1->flags & flagwprot) error(errinvalidaccess);
  1286.     file = filecheck(token1, openwrite);
  1287.     if (file == NULL) error(errioerror);
  1288.     if (token2->type != typeint) error(errtypecheck);
  1289.     if (putc(token2->value.ival, file->fptr) == EOF) error(errioerror);
  1290.     opernest -= 2;
  1291. }
  1292.  
  1293. /* writehexstring */
  1294.  
  1295. void opwritehexstring(void)
  1296. {   struct object *token1, *token2;
  1297.     struct file *file;
  1298.     FILE *fptr;
  1299.     char *sptr;
  1300.     int length, ch, num;
  1301.     if (opernest < 2) error(errstackunderflow);
  1302.     token2 = &operstack[opernest - 1];
  1303.     token1 = token2 - 1;
  1304.     if (token1->type != typefile) error(errtypecheck);
  1305.     if (token1->flags & flagwprot) error(errinvalidaccess);
  1306.     file = filecheck(token1, openwrite);
  1307.     if (file == NULL) error(errioerror);
  1308.     fptr = file->fptr;
  1309.     if (token2->type != typestring) error(errtypecheck);
  1310.     if (token2->flags & flagrprot) error(errinvalidaccess);
  1311.     length = token2->length;
  1312.     sptr = vmsptr(token2->value.vref);
  1313.     while (length--)
  1314.     {   num = *(unsigned char *)(sptr++);
  1315.         ch = num >> 4;
  1316.         ch += (ch < 10) ? '0' : 'a' - 10;
  1317.         if (putc(ch, fptr) == EOF) error(errioerror);
  1318.         ch = num & 15;
  1319.         ch += (ch < 10) ? '0' : 'a' - 10;
  1320.         if (putc(ch, fptr) == EOF) error(errioerror);
  1321.     }
  1322.     opernest -= 2;
  1323. }
  1324.  
  1325. /* writestring */
  1326.  
  1327. void opwritestring(void)
  1328. {   struct object *token1, *token2;
  1329.     struct file *file;
  1330.     if (opernest < 2) error(errstackunderflow);
  1331.     token2 = &operstack[opernest - 1];
  1332.     token1 = token2 - 1;
  1333.     if (token1->type != typefile) error(errtypecheck);
  1334.     if (token1->flags & flagwprot) error(errinvalidaccess);
  1335.     file = filecheck(token1, openwrite);
  1336.     if (file == NULL) error(errioerror);
  1337.     if (token2->type != typestring) error(errtypecheck);
  1338.     if (token2->flags & flagrprot) error(errinvalidaccess);
  1339.     putmem(file->fptr, vmsptr(token2->value.vref), token2->length);
  1340.     opernest -= 2;
  1341. }
  1342.  
  1343. /* xcheck */
  1344.  
  1345. void opxcheck(void)
  1346. {   struct object token, *token1;
  1347.     int bool;
  1348.     if (opernest < 1) error(errstackunderflow);
  1349.     token1 = &operstack[opernest - 1];
  1350.     bool = ((token1->flags & flagexec) != 0);
  1351.     token.type = typebool;
  1352.     token.flags = 0;
  1353.     token.length = 0;
  1354.     token.value.ival = bool;
  1355.     *token1 = token;
  1356. }
  1357.  
  1358. /* xor */
  1359.  
  1360. void opxor(void)
  1361. {   struct object *token1, *token2;
  1362.     if (opernest < 2) error(errstackunderflow);
  1363.     token2 = &operstack[opernest - 1];
  1364.     token1 = token2 - 1;
  1365.     if ((token1->type == typebool && token2->type == typebool) ||
  1366.         (token1->type == typeint  && token2->type == typeint))
  1367.         token1->value.ival ^= token2->value.ival;
  1368.     else
  1369.         error(errtypecheck);
  1370.     opernest--;
  1371. }
  1372.  
  1373. /* Initialise the operators (2) */
  1374.  
  1375. void initop2(void)
  1376. {   systemop(opindex,            "index");
  1377.     systemop(opknown,            "known");
  1378.     systemop(ople,               "le");
  1379.     systemop(oplength,           "length");
  1380.     systemop(opln,               "ln");
  1381.     systemop(opload,             "load");
  1382.     systemop(oplog,              "log");
  1383.     systemop(oploop,             "loop");
  1384.     systemop(oplt,               "lt");
  1385.     systemop(opmaxlength,        "maxlength");
  1386.     systemop(opmod,              "mod");
  1387.     systemop(opmul,              "mul");
  1388.     systemop(opne,               "ne");
  1389.     systemop(opneg,              "neg");
  1390.     systemop(opnoaccess,         "noaccess");
  1391.     systemop(opnot,              "not");
  1392.     systemop(opnull,             "null");
  1393.     systemop(opor,               "or");
  1394.     systemop(oppackedarray,      "packedarray");
  1395.     systemop(oppop,              "pop");
  1396.     systemop(opprint,            "print");
  1397.     systemop(opprompts,          "prompts");
  1398.     systemop(oppstack,           "pstack");
  1399.     systemop(opput,              "put");
  1400.     systemop(opputinterval,      "putinterval");
  1401.     systemop(opquit,             "quit");
  1402.     systemop(oprcheck,           "rcheck");
  1403.     systemop(oprand,             "rand");
  1404.     systemop(opread,             "read");
  1405.     systemop(opreadhexstring,    "readhexstring");
  1406.     systemop(opreadline,         "readline");
  1407.     systemop(opreadonly,         "readonly");
  1408.     systemop(opreadstring,       "readstring");
  1409.     systemop(oprepeat,           "repeat");
  1410.     systemop(opresetfile,        "resetfile");
  1411.     systemop(oprestore,          "restore");
  1412.     systemop(oproll,             "roll");
  1413.     systemop(opround,            "round");
  1414.     systemop(oprrand,            "rrand");
  1415.     systemop(oprun,              "run");
  1416.     systemop(opsave,             "save");
  1417.     systemop(opsearch,           "search");
  1418.     systemop(opsetpacking,       "setpacking");
  1419.     systemop(opsin,              "sin");
  1420.     systemop(opsqrt,             "sqrt");
  1421.     systemop(opsrand,            "srand");
  1422.     systemop(opstack,            "stack");
  1423.     systemop(opstatus,           "status");
  1424.     systemop(opstop,             "stop");
  1425.     systemop(opstopped,          "stopped");
  1426.     systemop(opstore,            "store");
  1427.     systemop(opstring,           "string");
  1428.     systemop(opsub,              "sub");
  1429.     systemop(optoken,            "token");
  1430.     systemop(optruncate,         "truncate");
  1431.     systemop(optype,             "type");
  1432.     systemop(opusertime,         "usertime");
  1433.     systemop(opvmhwm,            "vmhwm");
  1434.     systemop(opvmstatus,         "vmstatus");
  1435.     systemop(opwcheck,           "wcheck");
  1436.     systemop(opwhere,            "where");
  1437.     systemop(opwrite,            "write");
  1438.     systemop(opwritehexstring,   "writehexstring");
  1439.     systemop(opwritestring,      "writestring");
  1440.     systemop(opxcheck,           "xcheck");
  1441.     systemop(opxor,              "xor");
  1442. }
  1443.  
  1444. /* End of file "postop2.c" */
  1445.